#include "taskQueue.h"
#include "threadPool.h"

int exitPipe[2];
int time1_flag = 1;
void handler(int signum)
{
    printf("start exit thread\n");
    write(exitPipe[1], " ", 1);
}

int main(int argc, char *argv[])
{
    ARGS_CHECK(argc, 3);
    pipe(exitPipe);
    if (fork() != 0)
    {
        close(exitPipe[0]);
        signal(SIGUSR1, handler);
        wait(NULL);
        exit(0);
    }

    close(exitPipe[1]);
    threadPool_t threadPool;
    initThreadPool(&threadPool, 3);
    makeWorker(&threadPool);
    int sockfd;
    tcpInit(argv[1], argv[2], &sockfd);
    int epfd = epoll_create(1);
    epollAdd(epfd, sockfd);
    epollAdd(epfd, exitPipe[0]);
    struct epoll_event readySet[10];

    // char name_table[1024][64] = {{0}};
    char username[64];
    client_info_t user_tbl[1024];
    bzero(user_tbl, sizeof(user_tbl));
    // int isNetfdLogin[1024] = {0};
    //
    //
    CircularQueue cir_queue;
    initQueue_cir(&cir_queue);

    time_t passtime = 0;
    threadPool.sockfd = sockfd;
    while (1)
    {
        time_t pretime = time(NULL);
        int readyNum = epoll_wait(epfd, readySet, 10, 1000);
        time_t aftertime = time(NULL);
        passtime += aftertime - pretime;

        if (readyNum == 0)
        {
            timeout_exit(-1, &passtime, &time1_flag, &cir_queue);
        }
        for (int i = 0; i < readyNum; ++i)
        {
            if (readySet[i].data.fd == sockfd)
            {
                int netfd = accept(sockfd, NULL, NULL);

               //
                timeout_exit(netfd, &passtime, &time1_flag, &cir_queue);
               printf("ready id is %d\n", netfd);
                //

                users_login(&threadPool, netfd, user_tbl);
                strcpy(user_tbl[netfd].username, username);
                epollAdd(epfd, netfd);
            }
            else if (readySet[i].data.fd == exitPipe[0])
            {
                printf("threadPool is going to exit!\n");
                pthread_mutex_lock(&threadPool.taskQueue.mutex);
                threadPool.exitflag = 1;
                pthread_cond_broadcast(&threadPool.taskQueue.cond);
                pthread_mutex_unlock(&threadPool.taskQueue.mutex);

                for (int j = 0; j < 3; ++j)
                {
                    pthread_join(threadPool.tidArr[j], NULL);
                }
                printf("done\n");
                pthread_exit(NULL);
            }
            else
            {
                //printf("%d\n",readySet[i].data.fd);
                printf("ready id is %d\n", readySet[i].data.fd);
                timeout_exit(readySet[i].data.fd, &passtime, &time1_flag, &cir_queue);
                // epollAdd(epfd, readySet[i].data.fd);
                int ret = cmd_execute(&threadPool, readySet[i].data.fd, sockfd, user_tbl);
                if (ret == -1)
                {
                    bzero(&(user_tbl[readySet[i].data.fd]), sizeof(client_info_t));
                    epollDel(epfd, readySet[i].data.fd);
                }
            }
        }
    }
    return 0;
}
